﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using KC.Business.Bugs;
using KC.DataAccess.BuggerAll;

namespace KC.Tests
{
	[TestClass()]
	public class BugLoggerTest
	{
		public TestContext TestContext { get; set; }

		#region GetCategory tests

		[TestMethod()]
		public void GetCategoryTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			foreach (int CatID in Enum.GetValues(typeof(KnownCategory)))
				if ((KnownCategory)CatID != KnownCategory.Invalid)
					Assert.AreEqual(CatID, BugLogger.GetCategory((KnownCategory)CatID, ref dc).ID);
			dc.Dispose();
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException), "Can't use a null datacontext")]
		public void GetCategoryNullTest()
		{
			BuggerAllDataContext dc = null;
			BugLogger.GetCategory(KnownCategory.General, ref dc);
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentOutOfRangeException), "Cannot log using Invalid Category")]
		public void GetCategoryInvalidTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			BugLogger.GetCategory(KnownCategory.Invalid, ref dc);
		}

		#endregion GetCategory tests
		#region GetProject tests

		[TestMethod()]
		public void GetProjectTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			foreach (int ProjectID in Enum.GetValues(typeof(KnownProject)))
				if ((KnownProject)ProjectID != KnownProject.Invalid)
					Assert.AreEqual(ProjectID, BugLogger.GetProject((KnownProject)ProjectID, ref dc).ID);
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException), "Can't use a null datacontext")]
		public void GetProjectNullTest()
		{
			BuggerAllDataContext dc = null;
			BugLogger.GetProject(KnownProject.BuggerAll, ref dc);
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentOutOfRangeException), "Cannot log using Invalid Project")]
		public void GetProjectInvalidTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			BugLogger.GetProject(KnownProject.Invalid, ref dc);
		}

		#endregion GetProject tests
		#region GetPriority tests

		[TestMethod()]
		public void GetPriorityTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			foreach (int PriorityID in Enum.GetValues(typeof(KnownPriority)))
				if ((KnownPriority)PriorityID != KnownPriority.Invalid)
					Assert.AreEqual(PriorityID, BugLogger.GetPriority((KnownPriority)PriorityID, ref dc).ID);
			dc.Dispose();
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException), "Can't use a null datacontext")]
		public void GetPriorityNullTest()
		{
			BuggerAllDataContext dc = null;
			BugLogger.GetPriority(KnownPriority.Critical, ref dc); 
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentOutOfRangeException), "Cannot log using Invalid Priority")]
		public void GetPriorityInvalidTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext(); 
			BugLogger.GetPriority(KnownPriority.Invalid, ref dc);
		}

		#endregion GetPriority tests
		#region GetStatus tests

		[TestMethod()]
		public void GetStatusTest()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			foreach (int StatusID in Enum.GetValues(typeof(KnownStatus)))
				if ((KnownStatus)StatusID != KnownStatus.Invalid)
					Assert.AreEqual(StatusID, BugLogger.GetStatus((KnownStatus)StatusID, ref dc).ID);
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException), "Can't use a null datacontext")]
		public void GetStatusNullTest()
		{
			BuggerAllDataContext dc = null;
			BugLogger.GetStatus(KnownStatus.Closed, ref dc);
		}
		[TestMethod]
		[ExpectedException(typeof(ArgumentOutOfRangeException), "Cannot log using Invalid Status")]
		public void GetStatusInvalidTeset()
		{
			BuggerAllDataContext dc = new BuggerAllDataContext();
			BugLogger.GetStatus(KnownStatus.Invalid, ref dc);
		}

		#endregion GetStatus tests

		[TestMethod()]
		public void WriteTest()
		{
			string desc = "Test bug, ignore me";
			string detail = DateTime.Now.Ticks.ToString();

			BuggerAllDataContext dc = new BuggerAllDataContext();
			IQueryable<Bug> bugs = from b in dc.Bugs where b.Description == desc select b;
			IQueryable<BugStatusChange> bugstatuschanges = from bs in dc.BugStatusChanges where bugs.Contains(bs.Bug) select bs;
			dc.BugStatusChanges.DeleteAllOnSubmit(bugstatuschanges);
			dc.Bugs.DeleteAllOnSubmit(bugs);
			dc.SubmitChanges();
			System.Threading.Thread.Sleep(100);
			
			BugLogger.Write(KnownCategory.General, KnownPriority.WouldBeNice, KnownProject.BuggerAll, desc, detail, null);
			System.Threading.Thread.Sleep(100);

			bugs = from b in dc.Bugs where b.Description == desc select b;
			Assert.AreEqual(1, bugs.Count());

			Bug bug = bugs.First();
			Assert.AreEqual(desc, bug.Description);
			Assert.AreEqual(detail, bug.Detail);
			Assert.AreEqual(((int)KnownCategory.General), bug.CategoryID);
			Assert.AreEqual(((int)KnownPriority.WouldBeNice), bug.PriorityID);
			Assert.AreEqual(((int)KnownProject.BuggerAll), bug.ProjectID);

			bugstatuschanges = from b in dc.BugStatusChanges where b.BugID == bug.ID select b;
			Assert.AreEqual(bugstatuschanges.Count(), 1);
			BugStatusChange bsc = bugstatuschanges.First();
			Assert.AreEqual((int)KnownStatusChangeReason.Created, bsc.BugStatusChangeReason.ID);

			dc.BugStatusChanges.DeleteAllOnSubmit(bugstatuschanges);
			dc.SubmitChanges();
			dc.Bugs.DeleteAllOnSubmit(from b in dc.Bugs where b.Description == desc select b);
			dc.SubmitChanges();
		}
	}
}
